package net.sf.hibernate.id;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import net.sf.hibernate.HibernateException;
import net.sf.hibernate.dialect.Dialect;
import net.sf.hibernate.engine.SessionImplementor;
import net.sf.hibernate.type.Type;
import net.sf.hibernate.util.PropertiesHelper;
import net.sf.hibernate.util.StringHelper;

/**
 * <p>Title: TianYi BBS</p>
 * <p>Description: TianYi BBS System</p>
 * <p>Copyright: Copyright (c) 2004</p>
 * <p>Company: LAOER.COM/TIANYISOFT.NET</p>
 * @author laoer
 * @version 6.0
 */

public class TableCustomGenerator
    implements PersistentIdentifierGenerator, Configurable {

  public static final String COLUMN = "column";
  public static final String TABLE = "table";
  public static final String ID = "id";
  public static final String INCREMENT = "increment";

  private static final Log log = LogFactory.getLog(TableCustomGenerator.class);

  private String tableName;
  private String columnName;
  private int rowid;
  private int increment;
  private String query;
  private String update;

  public TableCustomGenerator() {
  }

  public void configure(Type type, Properties params, Dialect dialect) {
    this.tableName = PropertiesHelper.getString(TABLE, params, "BBSCS_TABLEID");
    this.columnName = PropertiesHelper.getString(COLUMN, params, "IDValue");
    this.rowid = PropertiesHelper.getInt(ID, params, 1);
    this.increment = PropertiesHelper.getInt(INCREMENT, params, 15);
    String schemaName = params.getProperty(SCHEMA);
    if (schemaName != null && tableName.indexOf(StringHelper.DOT) < 0) {
      tableName = schemaName + '.' + tableName;
    }
    query = "select " + columnName + " from " + tableName + " where id = ?";
    if (dialect.supportsForUpdate()) {
      //query += " for update";
    }
    update = "update " + tableName + " set " + columnName +
        " = ? where id = ? and " + columnName + " = ?";
    TableID.tableName = tableName;
    TableID.columnName = columnName;
    TableID.INCREMENT = increment;
    TableID.query = query;
    TableID.update = update;
  }

  public String[] sqlCreateStrings(Dialect dialect) throws net.sf.hibernate.
      HibernateException {
    return new String[] {
        "create table " + tableName + " ( id  " +
        dialect.getTypeName(Types.INTEGER) + " " + columnName + " " +
        dialect.getTypeName(Types.BIGINT) + " )",
        "insert into " + tableName + " values ( " + rowid + ",0 )"
    };
  }

  public String sqlDropString(Dialect dialect) throws net.sf.hibernate.
      HibernateException {
    StringBuffer sqlDropString = new StringBuffer()
        .append("drop table ");
    if (dialect.supportsIfExistsBeforeTableName()) {
      sqlDropString.append("if exists ");
    }
    sqlDropString.append(tableName)
        .append(dialect.getCascadeConstraintsString());
    if (dialect.supportsIfExistsAfterTableName()) {
      sqlDropString.append(" if exists");
    }
    return sqlDropString.toString();
  }

  public Object generatorKey() {
    return tableName;
  }

  public Serializable generate(SessionImplementor session, Object object) throws
      java.sql.SQLException, net.sf.hibernate.HibernateException {
    return new Long(TableID.nextID(rowid, session));
  }

}
